#include "OiPCH.hpp"

namespace Oi
{
    namespace PLScannerCore
    {

        class UserManageImpl : public Impl<UserManage>
        {
        public:
            QMap<QString, UserParams> _params;
            UserParams _default;

            QString _current;
        };


        UserManage::UserManage()
        {
            OI_I(UserManage);
            loadParams();
        }

        bool UserManage::isValid()
        {
            OI_F(UserManage);
            return !d->_params.isEmpty();
        }

        void UserManage::loadParams()
        {
            OI_F(UserManage);
            d->_params.clear();

            auto rootDir = Core::OiGetPermanentDir(RootDir).replace("\\", "/");
            auto oemDir = rootDir + "/oem";

            if(!QDir(oemDir).exists())
            {
                QDir().mkpath(oemDir);
            }

            auto fileName = oemDir + "/user.json";

            if(!QFileInfo::exists(fileName))
            {
                return;
            }

            QFile jsonReadFile(fileName);

            QByteArray bytes;

            if(jsonReadFile.open(QFile::ReadOnly))
            {
                bytes = jsonReadFile.readAll();
                jsonReadFile.close();
            }
            else
            {
                return;
            }

            QJsonParseError jsonError;

            QJsonDocument doucment = QJsonDocument::fromJson(bytes, &jsonError);

            if(doucment.isNull() || jsonError.error != QJsonParseError::NoError)
                return;

            if(doucment.isArray())
            {
                auto ms = doucment.array();
                for(auto& m : ms)
                {
                    auto mo = m.toObject();
                    if(mo.contains("id"))
                    {
                        auto& param = d->_params[mo["id"].toString()];
                        param.id = mo["id"].toString();
                        if(mo.contains("name")) param.name = mo["name"].toString();
                        if(mo.contains("permission")) param.permission = mo["permission"].toInt();
                        if(mo.contains("password")) param.password = mo["password"].toString();
                    }
                }
            }
        }

        void UserManage::saveParams()
        {
            OI_F(UserManage);

            QJsonArray ms;

            for(auto& opi = d->_params.begin(); opi != d->_params.end(); opi++)
            {
                QJsonObject mo;
                mo["id"] = opi->id;
                mo["name"] = opi->name;
                mo["permission"] = opi->permission;
                mo["password"] = opi->password;

                ms.append(mo);
            }

            QJsonDocument document;
            document.setArray(ms);
            QByteArray jsonByteArray = document.toJson(QJsonDocument::Indented);

            auto rootDir = Core::OiGetPermanentDir(RootDir).replace("\\", "/");
            auto oemDir = rootDir + "/oem";

            if(!QDir(oemDir).exists())
            {
                QDir().mkpath(oemDir);
            }

            auto fileName = oemDir + "/user.json";

            QFile jsonWriteFile(fileName);

            if(!jsonWriteFile.open(QFile::WriteOnly))
            {
                return;
            }

            jsonWriteFile.write(jsonByteArray);

            jsonWriteFile.close();
        }

        QString UserManage::current() const
        {
            return OI_IMPL()->_current;
        }

        int UserManage::setCurrent(const QString id, QString password)
        {
            OI_F(UserManage);

            if (id.isEmpty())
            {
                d->_current = QString();
                return 1;
            }

            if (!d->_params.contains(id))
            {
                return 2;
            }

            if (d->_params[id].password != password)
            {
                return 3;
            }

            d->_current = id;

            Core::OiSettings()->setValue("CurrentUser", id);
        
            return 0;
        }

        QString UserManage::name(QString id) const
        {
            OI_C(UserManage);

            if (id.isEmpty())
            {
                id = current();
            }

            if (id.isEmpty())
            {
                return QString();
            }

            if(d->_params.contains(id))
            {
                return d->_params[id].name;
            }
            else
            {
                return QString();
            }
        }

        int UserManage::team(QString id /*= QString()*/) const
        {
            OI_C(UserManage);

            if(id.isEmpty())
            {
                id = current();
            }

            if(id.isEmpty())
            {
                return 0;
            }

            if(d->_params.contains(id))
            {
                return d->_params[id].team;
            }
            else
            {
                return 0;
            }
        }

        int UserManage::permission(QString id) const
        {
            OI_C(UserManage);

            if(id.isEmpty())
            {
                id = current();
            }

            if(id.isEmpty())
            {
                return 0;
            }

            if(d->_params.contains(id))
            {
                return d->_params[id].permission;
            }
            else
            {
                return 0;
            }
        }

        QString UserManage::password(QString id) const
        {
            OI_C(UserManage);

            if(id.isEmpty())
            {
                id = current();
            }

            if(id.isEmpty())
            {
                return QString();
            }

            if(d->_params.contains(id))
            {
                return d->_params[id].password;
            }
            else
            {
                return QString();
            }
        }


        QStringList UserManage::users() const
        {
            return OI_IMPL()->_params.keys();
        }

        UserParams& UserManage::params(QString id)
        {
            OI_F(UserManage);
            if (d->_params.contains(id))
            {
                return d->_params[id];
            }
            else
            {
                return d->_default;
            }
        }

        QMap<QString, UserParams>& UserManage::paramsMap()
        {
            return OI_IMPL()->_params;
        }

        UserManage* UserManage::instance()
        {
            static UserManage s_users;
            return &s_users;
        }
    }
}